#include "controller.h"

using namespace G3;

//==============================================================================
// Global variables
//==============================================================================
G3::CONTROLLER_MGR G3::ControllerManager;

//==============================================================================
// Constructors
//==============================================================================
G3::CONTROLLER::CONTROLLER () {
	name = "Nameless";

	enabled = true;
}

G3::ROTATION_CTRL::ROTATION_CTRL () {
	name = "Rotation";
}

G3::TRANSLATION_CTRL::TRANSLATION_CTRL () {
	name = "Translation";
}

G3::SCALE_CTRL::SCALE_CTRL () {
	name = "Scale";
}

G3::CONTROLLER_MGR::CONTROLLER_MGR () {
    num_controllers_total = 0;
}

G3::CONTROLLER_MGR::~CONTROLLER_MGR () {
    num_controllers_total = 0;
}

//==============================================================================
// = operators
//==============================================================================
CONTROLLER& CONTROLLER::operator=(const CONTROLLER &c) {
    matrix = c.matrix;
	name = c.name;
	enabled = c.enabled;

	return *this;
}

ROTATION_CTRL& ROTATION_CTRL::operator=(const ROTATION_CTRL &c) {
	rotation = c.rotation;

	return *this;
}

TRANSLATION_CTRL& TRANSLATION_CTRL::operator=(const TRANSLATION_CTRL &c) {
	translation = c.translation;

	return *this;
}

SCALE_CTRL& SCALE_CTRL::operator=(const SCALE_CTRL &c) {
	scale = c.scale;

	return *this;
}

//==============================================================================
// Gets Controller type
//==============================================================================
CONTROLLER_TYPE G3::CONTROLLER::GetType () {
	return CT_BASE;
}

CONTROLLER_TYPE G3::ROTATION_CTRL::GetType () {
	return CT_ROTATION;
}

CONTROLLER_TYPE G3::TRANSLATION_CTRL::GetType () {
	return CT_TRANSLATION;
}

CONTROLLER_TYPE G3::SCALE_CTRL::GetType () {
	return CT_SCALE;
}

//==============================================================================
// Updates a controller
//==============================================================================
void G3::CONTROLLER::Update (double elapsedTime) {

}

void G3::ROTATION_CTRL::Update (double elapsedTime) {
	if (enabled) {
		rotation.CreateFromAxisAngle (1.0f, angles * elapsedTime);
		matrix = rotation.GetMatrix ();
	} else
		matrix.GetIdentity ();
}

void G3::TRANSLATION_CTRL::Update (double elapsedTime) {
	if (enabled) {
		matrix.GetIdentity ();
		matrix.Translate (translation * elapsedTime);
	} else
		matrix.GetIdentity ();
}

void G3::SCALE_CTRL::Update (double elapsedTime) {
	if (enabled) {
		matrix.GetIdentity ();
		matrix.Scale (scale);
	} else
		matrix.GetIdentity ();
}

//==============================================================================
// Controller-specific
//==============================================================================
void ROTATION_CTRL::SetRotation (float angle, G3::VEC3F axis) {
	angles = axis * angle;
}

void TRANSLATION_CTRL::SetTranslation (G3::VEC3F axis) {
	translation = axis;
}

void SCALE_CTRL::SetScale (G3::VEC3F axis) {
	scale = axis;
}

//==============================================================================
// Adds a controller
//==============================================================================
int G3::CONTROLLER_MGR::AddController (CONTROLLER controller) {
	pair<map<int, CONTROLLER>::iterator, bool> ret;
	static map<int, CONTROLLER>::iterator lit = controller_map.begin ();

	lit = controller_map.insert (lit, pair<int, CONTROLLER> (num_controllers_total, controller));
	num_controllers_total++;
	return lit->first;
}

//==============================================================================
// Removes a controller
//==============================================================================
bool G3::CONTROLLER_MGR::RemoveController (int cID) {
	return (controller_map.erase (cID) != 0);
}

//==============================================================================
// Gets a controller
//==============================================================================
CONTROLLER *G3::CONTROLLER_MGR::GetController (int cID) {
	map<int, CONTROLLER>::iterator it = controller_map.find (cID);
	if (it != controller_map.end ())
		return &it->second;
	return NULL;
}

//==============================================================================
// Updates all of the controllers
//==============================================================================
void G3::CONTROLLER_MGR::UpdateControllers (double elapsedTime) {
	map<int, CONTROLLER>::iterator it = controller_map.begin ();

	while (it != controller_map.end ()) {
		it->second.Update (elapsedTime);
		it++;
	}
}
